package com.xh3140.xwidget.recycler;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.Log;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.recyclerview.widget.RecyclerView;

/**
 * RecyclerView分割线(去除最后一条线)
 *
 * @see androidx.recyclerview.widget.DividerItemDecoration
 */
@SuppressWarnings("unused")
public class RecyclerLinearDivider extends RecyclerView.ItemDecoration {
  public static final int HORIZONTAL = LinearLayoutCompat.HORIZONTAL;
  public static final int VERTICAL = LinearLayoutCompat.VERTICAL;
  private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
  private static final String TAG = RecyclerLinearDivider.class.getSimpleName();

  private final int mOrientation;
  private final Drawable mDivider;
  private final Rect mBounds = new Rect();

  public RecyclerLinearDivider(@NonNull Context context) {
    this(context, VERTICAL);
  }

  public RecyclerLinearDivider(@NonNull Context context, int orientation) {
    final TypedArray a = context.obtainStyledAttributes(ATTRS);
    final Drawable drawable = a.getDrawable(0);
    if (drawable == null) {
      Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this "
              + "DividerItemDecoration. Please set that attribute all call setDrawable()");
    }
    a.recycle();
    mDivider = drawable;
    if (orientation != HORIZONTAL && orientation != VERTICAL) {
      throw new IllegalArgumentException("Invalid orientation. It should be either HORIZONTAL or VERTICAL");
    }
    mOrientation = orientation;
  }

  public RecyclerLinearDivider(@NonNull Drawable drawable) {
    this(drawable, VERTICAL);
  }

  public RecyclerLinearDivider(@NonNull Drawable drawable, int orientation) {
    mDivider = drawable;
    if (orientation != HORIZONTAL && orientation != VERTICAL) {
      throw new IllegalArgumentException("Invalid orientation. It should be either HORIZONTAL or VERTICAL");
    }
    mOrientation = orientation;
  }

  public static RecyclerLinearDivider of(@ColorInt int color, int thickness) {
    final GradientDrawable drawable = new GradientDrawable();
    drawable.setColor(ColorStateList.valueOf(color));
    drawable.setSize(thickness, thickness);
    return new RecyclerLinearDivider(drawable);
  }

  public static RecyclerLinearDivider of(@ColorInt int color, int thickness, int alpha) {
    final GradientDrawable drawable = new GradientDrawable();
    drawable.setColor(ColorStateList.valueOf(color));
    drawable.setSize(thickness, thickness);
    drawable.setAlpha(alpha);
    return new RecyclerLinearDivider(drawable);
  }

  @Override
  public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
    if (parent.getLayoutManager() == null || mDivider == null) {
      return;
    }
    if (mOrientation == VERTICAL) {
      drawVertical(canvas, parent);
    } else {
      drawHorizontal(canvas, parent);
    }
  }

  private void drawVertical(@NonNull Canvas canvas, @NonNull RecyclerView parent) {
    canvas.save();
    final int left;
    final int right;
    if (parent.getClipToPadding()) {
      left = parent.getPaddingLeft();
      right = parent.getWidth() - parent.getPaddingRight();
      canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
    } else {
      left = 0;
      right = parent.getWidth();
    }
    final int dividerCount = parent.getChildCount() - 1;
    for (int i = 0; i < dividerCount; ++i) {
      final View child = parent.getChildAt(i);
      parent.getDecoratedBoundsWithMargins(child, mBounds);
      final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
      final int top = bottom - mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(canvas);
    }
    canvas.restore();
  }

  private void drawHorizontal(@NonNull Canvas canvas, @NonNull RecyclerView parent) {
    canvas.save();
    final int top;
    final int bottom;
    if (parent.getClipToPadding()) {
      top = parent.getPaddingTop();
      bottom = parent.getHeight() - parent.getPaddingBottom();
      canvas.clipRect(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom);
    } else {
      top = 0;
      bottom = parent.getHeight();
    }
    final int dividerCount = parent.getChildCount() - 1;
    for (int i = 0; i < dividerCount; ++i) {
      final View child = parent.getChildAt(i);
      parent.getDecoratedBoundsWithMargins(child, mBounds);
      final int right = mBounds.right + Math.round(child.getTranslationX());
      final int left = right - mDivider.getIntrinsicWidth();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(canvas);
    }
    canvas.restore();
  }

  @Override
  public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
    if (mDivider == null) {
      outRect.set(0, 0, 0, 0);
      return;
    }
    if (mOrientation == VERTICAL) {
      outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
    } else {
      outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
    }
  }
}
